/*==============================================================================
 Copyright (c) 2010 QUALCOMM Incorporated.
 All Rights Reserved.
 Qualcomm Confidential and Proprietary

 @file
 ImageTargets.cpp

 @brief
 Sample for ImageTargets

 ==============================================================================*/


#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "string.h"
using namespace std;

#ifdef USE_OPENGL_ES_1_1
#include <GLES/gl.h>
#include <GLES/glext.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif

#include <QCAR/QCAR.h>
#include <QCAR/CameraDevice.h>
#include <QCAR/Renderer.h>
#include <QCAR/VideoBackgroundConfig.h>
#include <QCAR/Trackable.h>
#include <QCAR/Tool.h>
#include <QCAR/Tracker.h>
#include <QCAR/TrackerManager.h>
#include <QCAR/ImageTracker.h>
#include <QCAR/CameraCalibration.h>
#include <QCAR/UpdateCallback.h>
#include <QCAR/DataSet.h>

#include "SampleUtils.h"
#include "Texture.h"
#include "CubeShaders.h"
#include "Rectangle.h"



#ifdef __cplusplus
extern "C" {


#endif

// Textures:
int textureCount = 0;
Texture** textures = 0;
float* setRectangleVertices(float px, float size, float start_x, float start_y, float obj_width, float obj_height);

// OpenGL ES 2.0 specific:
#ifdef USE_OPENGL_ES_2_0
unsigned int shaderProgramID = 0;
GLint vertexHandle = 0;
GLint normalHandle = 0;
GLint textureCoordHandle = 0;
GLint mvpMatrixHandle = 0;
#endif

// Screen dimensions:
unsigned int screenWidth = 0;
unsigned int screenHeight = 0;

// Indicates whether screen is in portrait (true) or landscape (false) mode
bool isActivityInPortraitMode = false;

// The projection matrix used for rendering virtual objects:
QCAR::Matrix44F projectionMatrix;

// Constants:
static const float kObjectScale = 3.f;

QCAR::DataSet* dataSetMarket = 0;
QCAR::DataSet* dataSetMarket1 = 0;

bool switchDataSetAsap = false;

// Object to receive update callbacks from QCAR SDK


class ImageTargets_UpdateCallback: public QCAR::UpdateCallback 
{
	virtual void QCAR_onUpdate(QCAR::State& /*state*/) 
	{
		if (switchDataSetAsap) 
		{
			switchDataSetAsap = false;

			// Get the image tracker:
			
			
			
			
			
			QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
			QCAR::ImageTracker* imageTracker = static_cast<QCAR::ImageTracker*>(
				trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
			if (imageTracker == 0 || dataSetMarket == 0 || dataSetMarket1 == 0
					|| imageTracker->getActiveDataSet() == 0) {


				LOG("Failed to switch data set.");
				return;
			}

			if (imageTracker->getActiveDataSet() == dataSetMarket) {

				imageTracker->deactivateDataSet(dataSetMarket);
				imageTracker->activateDataSet(dataSetMarket1);
			} else {



				imageTracker->deactivateDataSet(dataSetMarket1);
				imageTracker->activateDataSet(dataSetMarket);
			}
		}
	}
};

ImageTargets_UpdateCallback updateCallback;

JNIEXPORT int JNICALL
Java_bachelorMain_ImageTargets_getOpenGlEsVersionNative(JNIEnv *, jobject)
{
#ifdef USE_OPENGL_ES_1_1        
	return 1;
#else
	return 2;
#endif
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_setActivityPortraitMode(JNIEnv *, jobject, jboolean isPortrait)
{
	isActivityInPortraitMode = isPortrait;
}



JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_switchDatasetAsap(JNIEnv *, jobject)
{
	switchDataSetAsap = true;
}


JNIEXPORT int JNICALL
Java_bachelorMain_ImageTargets_initTracker(JNIEnv *, jobject)
{
	LOG("Java_bachelorMain_ImageTargets_initTracker");

	// Initialize the image tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::Tracker* tracker = trackerManager.initTracker(QCAR::Tracker::IMAGE_TRACKER);
	if (tracker == NULL)
	{
		LOG("Failed to initialize ImageTracker.");
		return 0;
	}

	LOG("Successfully initialized ImageTracker.");
	return 1;
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_deinitTracker(JNIEnv *, jobject)
{
	LOG("Java_bachelorMain_ImageTargets_deinitTracker");

	// Deinit the image tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	trackerManager.deinitTracker(QCAR::Tracker::IMAGE_TRACKER);
}


JNIEXPORT int JNICALL
Java_bachelorMain_ImageTargets_loadTrackerData(JNIEnv *, jobject)
{
	LOG("Java_bachelorMain_ImageTargets_loadTrackerData");

	// Get the image tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::ImageTracker* imageTracker = static_cast<QCAR::ImageTracker*>(
			trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
	if (imageTracker == NULL)
	{
		LOG("Failed to load tracking data set because the ImageTracker has not"
				" been initialized.");
		return 0;
	}

	// Create the data sets:
	dataSetMarket = imageTracker->createDataSet();
	if (dataSetMarket == 0)

	{
		LOG("Failed to create a new tracking data.");
		return 0;
	}

	dataSetMarket1 = imageTracker->createDataSet();
	if (dataSetMarket1 == 0)



	{
		LOG("Failed to create a new tracking data.");
		return 0;
	}

	// Load the data sets:
	if (!dataSetMarket->load("Market.xml", QCAR::DataSet::STORAGE_APPRESOURCE))
	{
		LOG("Failed to load data set _ load datasets 1.");
		return 0;
	}
	/*

	 if (!dataSetMarket1->load("Market1.xml", QCAR::DataSet::STORAGE_APPRESOURCE))
	 {
	 LOG("Failed to load data set _ load datasets 2.");
	 return 0;
	 }*/


	// Activate the data set:
	if (!imageTracker->activateDataSet(dataSetMarket))
	{
		LOG("Failed to activate data set.");
		return 0;
	}

	LOG("Successfully loaded and activated data set.");
	return 1;
}


JNIEXPORT int JNICALL
Java_bachelorMain_ImageTargets_destroyTrackerData(JNIEnv *, jobject)
{
	LOG("Java_bachelorMain_ImageTargets_destroyTrackerData");

	// Get the image tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::ImageTracker* imageTracker = static_cast<QCAR::ImageTracker*>(
			trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
	if (imageTracker == NULL)
	{
		LOG("Failed to destroy the tracking data set because the ImageTracker has not"
				" been initialized.");
		return 0;
	}

	if (dataSetMarket != 0)


	{
		if (imageTracker->getActiveDataSet() == dataSetMarket &&
				!imageTracker->deactivateDataSet(dataSetMarket))
		{
			LOG("Failed to destroy the tracking data set StonesAndChips because the data set "
					"could not be deactivated.");
			return 0;
		}

		if (!imageTracker->destroyDataSet(dataSetMarket))
		{
			LOG("Failed to destroy the tracking data set Market.");
			return 0;
		}

		LOG("Successfully destroyed the data set Market.");
		dataSetMarket = 0;

	}

	if (dataSetMarket1 != 0)

	{
		if (imageTracker->getActiveDataSet() == dataSetMarket1 &&
				!imageTracker->deactivateDataSet(dataSetMarket1))
		{
			LOG("Failed to destroy the tracking data set Tarmac because the data set "
					"could not be deactivated.");
			return 0;
		}

		if (!imageTracker->destroyDataSet(dataSetMarket1))
		{
			LOG("Failed to destroy the tracking data set Market1.");
			return 0;
		}

		LOG("Successfully destroyed the data set Market1.");
		dataSetMarket1 = 0;


	}

	return 1;
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_onQCARInitializedNative(JNIEnv *, jobject)
{
	// Register the update callback where we handle the data set swap:
	QCAR::registerCallback(&updateCallback);

	// Comment in to enable tracking of up to 2 targets simultaneously and
	// split the work over multiple frames:
	QCAR::setHint(QCAR::HINT_MAX_SIMULTANEOUS_IMAGE_TARGETS, 2);
	QCAR::setHint(QCAR::HINT_IMAGE_TARGET_MULTI_FRAME_ENABLED, 1);
}




JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargetsRenderer_renderFrame(JNIEnv *env, jclass clazz, jobjectArray objectArray)
{    
	jobject element;
	jclass objectClazz;
	
	LOG("WILLKOMMEN IN RENDER_FRAME");


	// Clear color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Get the state from QCAR and mark the beginning of a rendering section
	QCAR::State state = QCAR::Renderer::getInstance().begin();

	// Explicitly render the Video Background
	QCAR::Renderer::getInstance().drawVideoBackground();

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);

//	glEnable (GL_BLEND); //transparenz?
	//    glEnable(GL_DEPTH_TEST);
	 //   glEnable(GL_BLEND);
	  //  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	
	LOG("todo: find trackable");
	// Trackable finden und textur zuweisen
	for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)
	{
		LOG("trackable");
		const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);
		LOG("done: trackable = state.getActiveTrackable(tIdx)");
		QCAR::Matrix44F modelViewMatrix =
		QCAR::Tool::convertPose2GLMatrix(trackable->getPose());
		LOG("done: t modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackable->getPose())");

		int textureIndex;

		LOG("start: markervergleich");
		int arraySize =  env->GetArrayLength(objectArray);
		for(int i=0; i<arraySize;i++)
		{	
			element = env->GetObjectArrayElement(objectArray, i);
			objectClazz = env->GetObjectClass(element);
			jfieldID markernameFieldId = env->GetFieldID(objectClazz, "name", "Ljava/lang/String;");
			jobject markernameObject = env->GetObjectField(element, markernameFieldId );
			jstring mname = (jstring)markernameObject;
			LOG("done: abfrage markername");
			const char* markername = env->GetStringUTFChars(mname, 0);
			if (strcmp(trackable->getName(),markername)==0)
			{
				LOG("done: strcmp(trackable->getName()");
				LOG(markername);
				textureIndex = i;
				LOG(trackable->getName());
				LOG("Index zugewiesen");
				break;
			}
			LOG("nicht");
			LOG(markername);
		}
		LOG("done: markervergleich");

		const Texture* const thisTexture = textures[textureIndex];


		//Objekt zeichnen und an Textur binden
		QCAR::Matrix44F modelViewProjection;

		SampleUtils::translatePoseMatrix(0.0f, 0.0f, kObjectScale,&modelViewMatrix.data[0]);
		SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,&modelViewMatrix.data[0]);
		SampleUtils::multiplyMatrix(&projectionMatrix.data[0],&modelViewMatrix.data[0] ,&modelViewProjection.data[0]);

		//Test
	//	glEnable(GL_CULL_FACE);
    //    glCullFace(GL_FRONT);
		//Test ende
		glUseProgram(shaderProgramID);

		element = env->GetObjectArrayElement(objectArray, textureIndex);
		objectClazz = env->GetObjectClass(element);
		
		jfieldID px_id = env->GetFieldID(objectClazz, "px", "F");
		float px = env->GetFloatField(element, px_id);
		
		jfieldID size_id = env->GetFieldID(objectClazz, "size", "F");
		float size = env->GetFloatField(element, size_id);
		
		jfieldID start_x_id = env->GetFieldID(objectClazz, "start_x", "F");
		float start_x = env->GetFloatField(element, start_x_id);
		
		jfieldID start_y_id = env->GetFieldID(objectClazz, "start_y", "F");
		float start_y = env->GetFloatField(element, start_y_id);
		
		jfieldID obj_width_id = env->GetFieldID(objectClazz, "object_width", "F");
		float obj_width = env->GetFloatField(element, obj_width_id);
		
		jfieldID obj_height_id = env->GetFieldID(objectClazz, "object_height", "F");
		float obj_height = env->GetFloatField(element, obj_height_id);
		
		
		//groesse des zu zeichnenden Rechtecks bestimmen
		setRectangleVertices(px, size, start_x, start_y, obj_width, obj_height);


		glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,(const GLvoid*) &rectangleVertices[0]);
		glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,(const GLvoid*) &rectangleNormals[0]);
		glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,(const GLvoid*) &rectangleTexCoords[0]);

		glEnableVertexAttribArray(vertexHandle);
		glEnableVertexAttribArray(normalHandle);
		glEnableVertexAttribArray(textureCoordHandle);

		glActiveTexture(GL_TEXTURE0);

		glEnable(GL_BLEND);
      //  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
	
		glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);

		glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,(GLfloat*)&modelViewProjection.data[0] );
			
//		glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		glDrawElements(GL_TRIANGLES, NUM_RECTANGLE_OBJECT_INDEX, GL_UNSIGNED_SHORT,(const GLvoid*) &rectangleIndices[0]);

		glDisable(GL_CULL_FACE);
        glCullFace(GL_BACK);
		
		SampleUtils::checkGlError("ImageTargets renderFrame");



	}


	glDisable(GL_DEPTH_TEST);
	
//	glDisable (GL_BLEND);
	glDisableVertexAttribArray(vertexHandle);
	glDisableVertexAttribArray(normalHandle);
	glDisableVertexAttribArray(textureCoordHandle);


	QCAR::Renderer::getInstance().end();
	LOG("done: renderFrame");
}

void configureVideoBackground() {




	// Get the default video mode:
	QCAR::CameraDevice& cameraDevice = QCAR::CameraDevice::getInstance();
	QCAR::VideoMode videoMode = cameraDevice.getVideoMode(
			QCAR::CameraDevice::MODE_DEFAULT);




	// Configure the video background
	QCAR::VideoBackgroundConfig config;
	config.mEnabled = true;
	config.mSynchronous = true;
	config.mPosition.data[0] = 0.0f;
	config.mPosition.data[1] = 0.0f;

	if (isActivityInPortraitMode) {


		//LOG("configureVideoBackground PORTRAIT");
		config.mSize.data[0] = videoMode.mHeight
				* (screenHeight / (float) videoMode.mWidth);
		config.mSize.data[1] = screenHeight;
		if (config.mSize.data[0] < screenWidth) {



			LOG(
					"Correcting rendering background size to handle missmatch between screen and video aspect ratios.");
			config.mSize.data[0] = screenWidth;
			config.mSize.data[1] = screenWidth
					* (videoMode.mWidth / (float) videoMode.mHeight);


		}
	} else {



		//LOG("configureVideoBackground LANDSCAPE");
		config.mSize.data[0] = screenWidth;
		config.mSize.data[1] = videoMode.mHeight
				* (screenWidth / (float) videoMode.mWidth);
		if (config.mSize.data[1] < screenHeight) {



			LOG(
					"Correcting rendering background size to handle missmatch between screen and video aspect ratios.");
			config.mSize.data[0] = screenHeight
					* (videoMode.mWidth / (float) videoMode.mHeight);
			config.mSize.data[1] = screenHeight;
		}
	}
	LOG(
			"Configure Video Background : Video (%d,%d), Screen (%d,%d), mSize (%d,%d)",
			videoMode.mWidth, videoMode.mHeight, screenWidth, screenHeight,
			config.mSize.data[0], config.mSize.data[1]);



	// Set the config:
	QCAR::Renderer::getInstance().setVideoBackgroundConfig(config);
}

float* setRectangleVertices(float px, float size, float start_x, float start_y, float obj_width, float obj_height)
	{
	    LOG("begin: setRectangleVertices");
		//Set Texture Sizes
		scalfactor = px/size; //px pro cm
		startingpoint_x = start_x;//55.00; //sp = unten links
		startingpoint_y = start_y; //-55.00;
		object_width = obj_width;//5.50;
		object_height= obj_height;//10.00;
		LOG("done: Vars zugewiesen");
		rectangleVertices[0] = startingpoint_x;
		rectangleVertices[1] = startingpoint_y;
		rectangleVertices[2] = 0.00f;
		rectangleVertices[3] = startingpoint_x + (object_width*scalfactor);
		rectangleVertices[4] = startingpoint_y;
		rectangleVertices[5] = 0.00f;
		rectangleVertices[6] = startingpoint_x + (object_width*scalfactor);
		rectangleVertices[7] =  startingpoint_y+(object_height*scalfactor);
		rectangleVertices[8] =  0.00f;
		rectangleVertices[9] = startingpoint_x;
		rectangleVertices[10] = startingpoint_y+(object_height*scalfactor);
		rectangleVertices[11] = 0.00f;
		LOG("done: WERTE NEU GESETZT");

		return rectangleVertices;
	}

	
	
JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_initApplicationNative(
		JNIEnv* env, jobject obj, jint width, jint height)
{
	LOG("Java_bachelorMain_ImageTargets_initApplicationNative");

	// Store screen dimensions
	screenWidth = width;
	screenHeight = height;

	// Handle to the activity class:
	jclass activityClass = env->GetObjectClass(obj);

	jmethodID getTextureCountMethodID = env->GetMethodID(activityClass,
			"getTextureCount", "()I");
	if (getTextureCountMethodID == 0)
	{
		LOG("Function getTextureCount() not found.");
		return;
	}

//	textureCount = (int) env->CallObjectMethod(obj, getTextureCountMethodID);
textureCount = env->CallIntMethod(obj, getTextureCountMethodID);

	if (!textureCount)
	{
		LOG("getTextureCount() returned zero.");
		return;
	}

	textures = new Texture*[textureCount];

	jmethodID getTextureMethodID = env->GetMethodID(activityClass,"getTexture", "(I)LbachelorMain/Texture;");


	if (getTextureMethodID == 0)
	{
		LOG("Function getTexture() not found.");
		return;
	}

	// Register the textures
	for (int i = 0; i < textureCount; ++i)
	{

		jobject textureObject = env->CallObjectMethod(obj, getTextureMethodID, i);
		if (textureObject == NULL)
		{
			LOG("GetTexture() returned zero pointer");
			return;
		}

		textures[i] = Texture::create(env, textureObject);
	}
	LOG("ImageTargets_initApplicationNative finished");

}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_deinitApplicationNative(JNIEnv* env, jobject obj)

{
	LOG("Java_bachelorMain_ImageTargets_deinitApplicationNative");

	// Release texture resources
	if (textures != 0)
	{
		for (int i = 0; i < textureCount; ++i)
		{
			delete textures[i];
			textures[i] = NULL;
		}

		delete[]textures;
		textures = NULL;

		textureCount = 0;
	}
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_startCamera(JNIEnv *,jobject)

{
	LOG("Java_bachelorMain_ImageTargets_startCamera");

	// Initialize the camera:
	if (!QCAR::CameraDevice::getInstance().init())
	return;

	// Configure the video background
	configureVideoBackground();

	// Select the default mode:
	if (!QCAR::CameraDevice::getInstance().selectVideoMode(
					QCAR::CameraDevice::MODE_DEFAULT))
	return;

	// Start the camera:
	if (!QCAR::CameraDevice::getInstance().start())
	return;

	// Uncomment to enable flash
	//if(QCAR::CameraDevice::getInstance().setFlashTorchMode(true))
	//	LOG("IMAGE TARGETS : enabled torch");

	// Uncomment to enable infinity focus mode, or any other supported focus mode
	// See CameraDevice.h for supported focus modes
//	if(QCAR::CameraDevice::getInstance().setFocusMode(QCAR::CameraDevice::FOCUS_MODE_INFINITY))
//	LOG("IMAGE TARGETS : enabled infinity focus");

	// Start the tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::Tracker* imageTracker = trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER);
	if(imageTracker != 0)
	imageTracker->start();
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_stopCamera(JNIEnv *,jobject)
{
	LOG("Java_bachelorMain_ImageTargets_stopCamera");

	// Stop the tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::Tracker* imageTracker = trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER);
	if(imageTracker != 0)
	imageTracker->stop();

	QCAR::CameraDevice::getInstance().stop();
	QCAR::CameraDevice::getInstance().deinit();
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargets_setProjectionMatrix(JNIEnv *, jobject)
{
	LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_setProjectionMatrix");

// Cache the projection matrix:
	const QCAR::CameraCalibration& cameraCalibration =
	QCAR::CameraDevice::getInstance().getCameraCalibration();
	projectionMatrix = QCAR::Tool::getProjectionGL(cameraCalibration, 2.0f,
			2000.0f);}


JNIEXPORT jboolean JNICALL
Java_bachelorMain_ImageTargets_activateFlash(JNIEnv*, jobject, jboolean flash)
{
    return QCAR::CameraDevice::getInstance().setFlashTorchMode((flash==JNI_TRUE)) ? JNI_TRUE : JNI_FALSE;
}


JNIEXPORT jboolean JNICALL
Java_bachelorMain_ImageTargets_autofocus(JNIEnv*, jobject)
{
    return QCAR::CameraDevice::getInstance().setFocusMode(QCAR::CameraDevice::FOCUS_MODE_TRIGGERAUTO) ? JNI_TRUE : JNI_FALSE;
}


JNIEXPORT jboolean JNICALL
Java_bachelorMain_ImageTargets_setFocusMode(JNIEnv*, jobject, jint mode)
{
    int qcarFocusMode;

    switch ((int)mode)
    {
        case 0:
            qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_NORMAL;
            break;
        
        case 1:
            qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_CONTINUOUSAUTO;
            break;
            
        case 2:
            qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_INFINITY;
            break;
            
        case 3:
            qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_MACRO;
            break;
    
        default:
            return JNI_FALSE;
    }
    
    return QCAR::CameraDevice::getInstance().setFocusMode(qcarFocusMode) ? JNI_TRUE : JNI_FALSE;
}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargetsRenderer_initRendering(
                                                    JNIEnv* env, jobject obj)
{
    LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_initRendering");

    // Define clear color
    glClearColor(0.0f, 0.0f, 0.0f, QCAR::requiresAlpha() ? 0.0f : 1.0f);
    
    // Now generate the OpenGL texture objects and add settings
    for (int i = 0; i < textureCount; ++i)
    {
        glGenTextures(1, &(textures[i]->mTextureID));
        glBindTexture(GL_TEXTURE_2D, textures[i]->mTextureID);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textures[i]->mWidth,
                textures[i]->mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                (GLvoid*)  textures[i]->mData);
    }
#ifndef USE_OPENGL_ES_1_1
  
    shaderProgramID     = SampleUtils::createProgramFromBuffer(cubeMeshVertexShader,
                                                            cubeFragmentShader);

    vertexHandle        = glGetAttribLocation(shaderProgramID,
                                                "vertexPosition");
    normalHandle        = glGetAttribLocation(shaderProgramID,
                                                "vertexNormal");
    textureCoordHandle  = glGetAttribLocation(shaderProgramID,
                                                "vertexTexCoord");
    mvpMatrixHandle     = glGetUniformLocation(shaderProgramID,
                                                "modelViewProjectionMatrix");

#endif

}


JNIEXPORT void JNICALL
Java_bachelorMain_ImageTargetsRenderer_updateRendering(
		JNIEnv* env, jobject obj, jint width, jint height)
{
	LOG("Java_bachelorMain_ImageTargetsRenderer_updateRendering");

	// Update screen dimensions
	screenWidth = width;
	screenHeight = height;

	// Reconfigure the video background
	configureVideoBackground();
}


#ifdef __cplusplus
}
#endif
